package lixp.security.config;

import lixp.security.handler.AuthAccessDeniedHandler;
import lixp.security.handler.AuthFailureHandler;
import lixp.security.handler.AuthSuccessHandler;
import lixp.security.handler.MyLogoutSuccessHandler;
import lixp.security.service.MyDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;


/**
 * 核心配置类
 */
@Configuration
@EnableWebSecurity //开启安全认证111
@EnableGlobalMethodSecurity( prePostEnabled = true, securedEnabled = true ) //开启注解认证
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    AuthAccessDeniedHandler authAccessDeniedHandler;

    @Autowired
    AuthFailureHandler authFailureHandler;

    @Autowired
    AuthSuccessHandler authSuccessHandler;

    @Autowired
    MyLogoutSuccessHandler myLogoutSuccessHandler;

    @Autowired
    AuthProvider authProvider;

    @Autowired
    MyDetailService myDetailService;

    @Autowired
    CustomPermissionEvaluator customPermissionEvaluator;


    /***注入自定义的CustomPermissionEvaluator,用于hasPermission注解的处理*/
//   public DefaultWebSecurityExpressionHandler webSecurityExpressionHandler(){
//       DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
//       handler.setPermissionEvaluator(customPermissionEvaluator);
//       return handler;
//   }


    /**
     * 用户认证配置
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /**
         * 指定用户认证时，默认从哪里获取认证用户信息有两种
         * 一个是authenticationProvider()
         * 一个是userDetailsService()
         * 建议使用authenticationProvider()，用这个密码认证的时候更灵活，可以按照自己的加密规则使用
         */
        auth.authenticationProvider(authProvider);
//        auth.userDetailsService(myDetailService);
    }

    /**
     * 核心配置，配置登录、登录成功、认证成功、认证失败等
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
//                .expressionHandler(webSecurityExpressionHandler())
                .antMatchers("/login").permitAll() //"/login"不进行权限验证
                .anyRequest().authenticated() //其他的需要登陆后才能访问
                .and()
                .formLogin()
                //登录请求
                .loginProcessingUrl("/login")
                //配置登录成功的自定义处理类
                .successHandler(authSuccessHandler)
                //配置登录失败的自定义处理类
                .failureHandler(authFailureHandler)
                .and()
                //loginProcessingUrl用于指定前后端分离的时候调用后台注销接口的名称
                .logout().logoutUrl("/logout")
                .logoutSuccessHandler(myLogoutSuccessHandler)
                .and()
                //配置没有权限的自定义处理类
                .exceptionHandling().accessDeniedHandler(authAccessDeniedHandler)
                .and()
                .cors()
                .and()
                .csrf().disable();// 取消跨站请求伪造防护
//        http.addFilterBefore(myAbstractSecurityInterceptor, FilterSecurityInterceptor.class);

    }


}
